home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Environments / PowerMacOberon feb96 / Source / IconElems.Mod (.txt) < prev    next >
Oberon Text  |  1994-10-13  |  7KB  |  188 lines

  1. Syntax10.Scn.Fnt
  2. Syntax10i.Scn.Fnt
  3. MODULE IconElems;    (* gri / mf 30.9.93 *)
  4.     IMPORT Input, Display, Oberon, Math, Viewers, Files, Printer, Texts, TextFrames, TextPrinter;
  5.     CONST
  6.         ticks = 1000; (* Oberon.Time ticks per second *)
  7.         IStag = 753; (* icon stretch tag *)
  8.         left = 2; middle = 1; right = 0; (* mouse keys *)
  9.         HSide = MAX(SET)+1; Side = 2*HSide; PDot = 3; (* dimensions *)
  10.         MaxN = 64; Sleep = 100; (* in ms *)
  11.     TYPE
  12.         Icon = ARRAY 2 OF RECORD
  13.             addr: LONGINT;
  14.             image: ARRAY Side+2 OF SET
  15.         END;
  16.         Elem = POINTER TO ElemDesc;
  17.         ElemDesc = RECORD (Texts.ElemDesc)
  18.         END;
  19.         Frame = POINTER TO RECORD(Display.FrameDesc) col: SHORTINT END;
  20.         NotifyMsg = RECORD(TextFrames.NotifyMsg) END;
  21.         N: LONGINT; (* no. of figurs *)
  22.         Task: Oberon.Task;
  23.         State: LONGINT; (* actual figure state *)
  24.         Fig: ARRAY MaxN OF Icon;
  25.     PROCEDURE EmptyFig;
  26.         VAR j: INTEGER;
  27.     BEGIN N := 1; j := 0;
  28.         WHILE j < Side DO
  29.             Fig[0, 0].image[j+1] := {};
  30.             Fig[0, 1].image[j+1] := {};
  31.             INC(j)
  32.         END;
  33.         Fig[0, 0].addr := Display.NewPattern(Fig[0, 0].image, HSide, Side);
  34.         Fig[0, 1].addr := Display.NewPattern(Fig[0, 1].image, HSide, Side)
  35.     END EmptyFig;
  36.     PROCEDURE LoadFig (file: ARRAY OF CHAR); (* read portable file format *)
  37.         VAR F: Files.File; R: Files.Rider; i, j: INTEGER;
  38.         PROCEDURE ReadSet (VAR s: SET);
  39.             VAR x: LONGINT; i: INTEGER;
  40.         BEGIN Files.ReadNum(R, x); s := {}; i := 0;
  41.             WHILE i < 32 DO
  42.                 IF ODD(x) THEN INCL(s, i) END;
  43.                 x := x DIV 2; INC(i)
  44.             END
  45.         END ReadSet;
  46.     BEGIN F := Files.Old(file);
  47.         IF F = NIL THEN EmptyFig; RETURN END;
  48.         Files.Set(R, F, 0); Files.ReadNum(R, N);
  49.         IF N # IStag THEN EmptyFig; RETURN END;
  50.         Files.ReadNum(R, N); i := 0;
  51.         WHILE i < N DO j := 0;
  52.             WHILE j < Side DO
  53.                 ReadSet(Fig[i, 0].image[j+1]);
  54.                 ReadSet(Fig[i, 1].image[j+1]);
  55.                 INC(j)
  56.             END;
  57.             Fig[i, 0].addr := Display.NewPattern(Fig[i, 0].image, HSide, Side);
  58.             Fig[i, 1].addr := Display.NewPattern(Fig[i, 1].image, HSide, Side);
  59.             INC(i)
  60.         END
  61.     END LoadFig;
  62.     PROCEDURE Draw (VAR icn: Icon; x, y, color: INTEGER);
  63.     BEGIN
  64.         Display.CopyPattern(color, icn[0].addr, x, y, Display.invert);
  65.         Display.CopyPattern(color, icn[1].addr, x + HSide, y, Display.invert)
  66.     END Draw;
  67.     PROCEDURE Print (VAR icn: Icon; x, y: INTEGER);
  68.         VAR i: INTEGER;
  69.         PROCEDURE PrintLine (x, y: INTEGER; line: SET);
  70.             VAR i, i0: INTEGER;
  71.         BEGIN i := 0;
  72.             WHILE i < HSide DO
  73.                 IF i IN line THEN i0 := i; INC(i);
  74.                     WHILE (i < HSide) & (i IN line) DO INC(i) END;
  75.                     Printer.ReplConst(x + (HSide-i)*PDot, y, (i-i0)*PDot, PDot)
  76.                 END;
  77.                 INC(i)
  78.             END
  79.         END PrintLine;
  80.     BEGIN i := 0;
  81.         WHILE i < Side DO
  82.             PrintLine(x, y + i*PDot, icn[0].image[i+1]);
  83.             PrintLine(x + HSide*PDot, y + i*PDot, icn[1].image[i+1]);
  84.             INC(i)
  85.         END
  86.     END Print;
  87.     PROCEDURE SaveScreen (x0, y0: INTEGER; keys: SET; col: SHORTINT);
  88.         VAR sum: SET; x, y, w, h: INTEGER; msg: Viewers.ViewerMsg; wakeUp: LONGINT;
  89.     BEGIN
  90.         Display.ReplConst(Display.white, x0, y0, Side, Side, Display.invert); sum := keys;
  91.         REPEAT
  92.             Input.Mouse(keys, x, y); sum := sum+keys; 
  93.             Oberon.DrawCursor(Oberon.Mouse, Oberon.Arrow, x, y)
  94.         UNTIL keys = {};
  95.         Display.ReplConst(Display.white, x0, y0, Side, Side, Display.invert);
  96.         IF sum # {left, middle, right} THEN
  97.             x := Oberon.UserTrack(x0); w := Oberon.DisplayWidth(x0);
  98.             y := Display.Bottom; h := Oberon.DisplayHeight(x0);
  99.             Oberon.RemoveMarks(x, y, w, h);
  100.             msg.id := Viewers.suspend; Viewers.Broadcast(msg);
  101.             Display.ReplConst(Display.black, 0, 0, w, h, Display.replace);
  102.             REPEAT
  103.                 Display.ReplConst(Display.black, x0, y0, Side, Side, Display.replace);
  104.                 INC(State); INC(x0, 10);
  105.                 IF x0+Side > x+w THEN x0 := x; INC(y0, Side);
  106.                     IF y0+Side > y+h THEN y0 := y END
  107.                 END;
  108.                 Draw(Fig[State MOD N], x0, y0, col);
  109.                 wakeUp := Oberon.Time() + Sleep*ticks DIV 1000;
  110.                 REPEAT UNTIL Oberon.Time() >= wakeUp
  111.             UNTIL Input.Available() > 0;
  112.             msg.id := Viewers.restore; Viewers.Broadcast(msg)
  113.         END
  114.     END SaveScreen;
  115.     PROCEDURE HandleFrame (F: Display.Frame; VAR M: Display.FrameMsg);
  116.         VAR r: INTEGER;
  117.     BEGIN
  118.         WITH F: Frame DO
  119.             IF M IS NotifyMsg THEN
  120.                 WITH M: NotifyMsg DO
  121.                     Draw(Fig[(State-1) MOD N], F.X, F.Y, F.col);
  122.                     Draw(Fig[State MOD N], F.X, F.Y, F.col)
  123.                 END
  124.             ELSIF M IS Oberon.InputMsg THEN
  125.                 WITH M: Oberon.InputMsg DO
  126.                     IF M.id = Oberon.track THEN Oberon.DrawCursor(Oberon.Mouse, Oberon.Arrow, M.X, M.Y) END
  127.                 END
  128.             END
  129.         END
  130.     END HandleFrame;
  131.     PROCEDURE Handle (E: Texts.Elem; VAR msg: Texts.ElemMsg);
  132.         VAR e: Elem; ch: CHAR; F: Frame;
  133.     BEGIN
  134.         WITH E: Elem DO
  135.             IF msg IS TextFrames.DisplayMsg THEN
  136.                 WITH msg: TextFrames.DisplayMsg DO
  137.                     IF ~msg.prepare THEN
  138.                         Draw(Fig[State MOD N], msg.X0, msg.Y0, msg.col);
  139.                         NEW(F); F.handle := HandleFrame; F.X := msg.X0; F.Y := msg.Y0; F.W := 64; F.H := 64; F.col := msg.col;
  140.                         msg.elemFrame := F
  141.                     END
  142.                 END
  143.             ELSIF msg IS TextPrinter.PrintMsg THEN
  144.                 WITH msg: TextPrinter.PrintMsg DO
  145.                     IF msg.prepare THEN
  146.                         E.W := Side * TextPrinter.Unit * PDot; E.H := E.W
  147.                     ELSE
  148.                         Print(Fig[State MOD N], msg.X0, msg.Y0);
  149.                         E.W := Side * TextFrames.Unit; E.H := E.W
  150.                     END
  151.                 END
  152.             ELSIF msg IS Texts.CopyMsg THEN
  153.                 NEW(e); Texts.CopyElem(E, e); msg(Texts.CopyMsg).e := e
  154.             ELSIF msg IS TextFrames.TrackMsg THEN
  155.                 WITH msg: TextFrames.TrackMsg DO
  156.                     IF middle IN msg.keys THEN SaveScreen(msg.X0, msg.Y0, msg.keys, msg.col) END
  157.                 END
  158.             ELSIF msg IS Texts.IdentifyMsg THEN
  159.                 WITH msg: Texts.IdentifyMsg DO
  160.                     msg.mod := "IconElems"; msg.proc := "New"
  161.                 END
  162.             ELSIF msg IS Texts.FileMsg THEN
  163.                 WITH msg: Texts.FileMsg DO
  164.                     IF msg.id = Texts.load THEN Files.Read(msg.r, ch) (* ignore in this version *)
  165.                     ELSIF msg.id = Texts.store THEN Files.Write(msg.r, 0X); (* version tag: used for future extensions *)
  166.                     END
  167.                 END
  168.             END
  169.         END
  170.     END Handle;
  171.     PROCEDURE Step;
  172.         VAR msg: NotifyMsg;
  173.     BEGIN INC(State); Viewers.Broadcast(msg); Task.time := Oberon.Time() + Sleep*ticks DIV 1000
  174.     END Step;
  175.     PROCEDURE New*;
  176.         VAR E: Elem;
  177.     BEGIN NEW(E); E.handle := Handle; Texts.new := E
  178.     END New;
  179.     PROCEDURE Insert*;
  180.         VAR E: Elem; m: TextFrames.InsertElemMsg;
  181.     BEGIN NEW(E); E.W := Side * TextFrames.Unit; E.H := E.W; E.handle := Handle; m.e := E;
  182.         Oberon.FocusViewer.handle(Oberon.FocusViewer, m)
  183.     END Insert;
  184. BEGIN
  185.     LoadFig("IconElems.Icon"); State := 0;
  186.     NEW(Task); Task.safe := FALSE; Task.handle := Step; Oberon.Install(Task)
  187. END IconElems.
  188.